home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d17 / proff.arc / PXXPARSE.C < prev    next >
Text File  |  1988-02-17  |  10KB  |  510 lines

  1. #include <stdio.h>
  2. #include <ctype.h>
  3. #include "proff.h"
  4. #include "debug.h"
  5. #include "lextab.h"
  6.  
  7. #define RUNOFF    1         /* recognise RUNOFF commands */
  8.  
  9. struct lexlist *xremove();
  10. char *strsave();
  11. struct hashlist *lookup();
  12.  
  13. char literal = NO;        /* literal flag             */
  14.  
  15. /*
  16.  * command - perform formatting command
  17.  *
  18.  */
  19. command(buf)
  20. char buf[];
  21. {
  22.     char token[MAXTOK], xtoken[MAXTOK], variable[MAXTOK], *defn;
  23.     char special[MAXTOK];
  24.     int argtyp, ct, at, spval, i, flags;
  25.     register int val, n, rest;
  26.     char onflag = FALSE; 
  27.     char offlag = FALSE;
  28.     struct lexlist *xp;
  29.  
  30.     dovar(tbuf1,buf);    /* use scratch buffer to expand variables */
  31.     strcpy(buf,tbuf1);
  32.  
  33.     i = 1;
  34.     n = getwrd(buf, &i, token);    /* get the command token */
  35.     rest = i;            /* remaining string */
  36.     ct = comtype(token, n, &defn, &flags);
  37.     if (ct == UNKNOWN)
  38.         return;
  39.     if (literal && ct != ELT) {    /* ignore while literal  */
  40.         put(buf);
  41.         return;
  42.     }
  43.  
  44. #ifdef DOUBLEWORD
  45.     if (flags == 2) {    /* check for 2-word command */
  46.         n = getwrd(buf, &i, xtoken);
  47.         if (n == 0) {
  48.             fprintf(stderr,"%c%s what ?\n", cchar, token);
  49.             return;
  50.         }
  51.         if ((at = comtype(xtoken, n, &defn, &flags)) == UNKNOWN) {
  52.             fprintf(stderr,"%c%s %s unknown.\n", cchar,
  53.             token,
  54.             xtoken);
  55.             return;
  56.         }
  57.         else
  58.             ct += at;
  59.     }
  60. #endif
  61.  
  62.     doesc(buf, variable, MAXLINE);    /* expand escapes */
  63.     n = getarg(buf, &i, xtoken);    /* first parameter*/
  64.     argtyp = '\n';    /* defaulted ** cludge ** */
  65.     val = 0;
  66.     if (n > 0) {
  67.         if (*xtoken == '+' || *xtoken == '-') {
  68.             argtyp = *xtoken;
  69.             val = atoi(xtoken+1);
  70.         }
  71.         else if (isdigit(*xtoken)) {
  72.             argtyp = 0;
  73.             val = atoi(xtoken);
  74.         }
  75.         else {
  76.             /* check some common flags */
  77.             if (strcmp("on",xtoken) == 0)
  78.                 onflag = TRUE;
  79.             else if (strcmp("off",xtoken) == 0)
  80.                 offlag = TRUE;
  81.         }
  82.     }
  83.  
  84.     switch(ct) {
  85.  
  86.     case MACRO:
  87.         eval(buf, defn);
  88.         break;
  89.     case FI:
  90.         lbrk();
  91.         fill = YES;
  92.         break;
  93.     case NF:
  94.         lbrk();
  95.         fill = NO;
  96.         break;
  97.     case BR:
  98.         lbrk();
  99.         break;
  100.     case LS:
  101.         set(&lsval, val, argtyp, 1, 1, HUGE);
  102.         break;
  103.     case CE:
  104.         lbrk();
  105.         if (onflag)
  106.             CEon = TRUE;
  107.         else if (offlag) {
  108.             CEon = FALSE;
  109.             ceval = 0;        /* reset */
  110.         }
  111.         else
  112.             set(&ceval, val, argtyp, 1, 0, HUGE);
  113.         break;
  114.     case UL:
  115.         if (onflag) {
  116.             ULon = TRUE;
  117.             break;
  118.         }
  119.         else if (offlag) {
  120.             ULon = FALSE;
  121.              ulval = 0;        /* reset */
  122.             break;
  123.         }
  124.         else
  125.             set(&ulval, val, argtyp, 0, 1, HUGE);
  126.  
  127.         if (!isdigit(*xtoken)) {
  128.             if (strcmp("all",xtoken) == 0) {
  129.                     ulblnk = '_';
  130.                     ulval = 0;
  131.             }
  132.             else if (strcmp("words",xtoken) == 0) {
  133.                 ulblnk = ' ';
  134.                 ulval = 0;
  135.             }
  136.         }
  137.         break;
  138.     case BD:
  139.         if (bolding == YES) {
  140.             if (onflag)
  141.                 BDon = TRUE;
  142.             else if (offlag) {
  143.                 BDon = FALSE;
  144.                 boval = 0;    /* reset */
  145.             }
  146.             else
  147.                 set(&boval, val, argtyp, 0, 1, HUGE);
  148.         }
  149.         break;
  150.     case HE:
  151.         gettl(buf, ehead, ehlim);
  152.         gettl(buf, ohead, ohlim);
  153.         break;
  154.     case FO:
  155.         gettl(buf, efoot, eflim);
  156.         gettl(buf, ofoot, oflim);
  157.         break;
  158.     case BP:
  159.         if (paging == NO)
  160.             break;
  161.         lbrk();
  162.         if (lineno > 0)
  163.             space(HUGE);
  164.         set(&curpag, val, argtyp, curpag+1, -HUGE, HUGE);
  165.         newpag = curpag;
  166.         break;
  167.     case SP:
  168.         set(&spval, val, argtyp, 1, 0, HUGE);
  169.         space(spval);
  170.         break;
  171.     case IN:
  172.         lbrk();
  173.         set(&inval, val, argtyp, 0, 0, rmval-1);
  174.         tival = inval;
  175.         break;
  176.     case RM:
  177.         set(&rmval, val, argtyp, PAGEWIDTH, tival+1, HUGE);
  178.         break;
  179.     case TI:
  180.         lbrk();
  181.         set(&tival, val, argtyp, 0, 0, rmval);
  182.         break;
  183.     case LEX:    /****/
  184.         if ((xp = xremove(xtoken,lextab)) != NULL) {
  185.             if (getwrd(buf, &i, variable) != 0)
  186.                 lexinstal(variable,xp->val,xp->flag,lextab);
  187.         }
  188.         else
  189.             fprintf(stderr,"%s undefined.\n",xtoken);
  190.         break;
  191.     case PN:    /****/
  192.         if (strcmp(xtoken,"roman") == 0)
  193.             roman = TRUE;
  194.         else if (strcmp(xtoken,"arabic") == 0)
  195.             roman = FALSE;
  196.         else
  197.             fprintf(stderr,"%c%s does not have %s option.\n",
  198.             cchar,token,xtoken);
  199.         break;
  200.     case IG:    /****/
  201.         break;
  202.     case SET:    /****/
  203.         if (n > 0) {
  204.             if (isdigit(*xtoken)) {
  205.                 fprintf(stderr,"illegal variable name %s\n",
  206.                 xtoken);
  207.                 break;
  208.             }
  209.             *variable = '\0';
  210.             n = getarg(buf, &i, variable);
  211.             if (n <= 0) {
  212.                 fprintf(stderr,"%s: ", xtoken);
  213.                 gets(variable);
  214.  
  215.             }
  216.             if (*variable != '\0')
  217.                 install(xtoken, variable, gentab);
  218.         }
  219.         else
  220.             fprintf(stderr,"%c%s needs a variable name.\n",
  221.             cchar, token);
  222.         break;
  223.     case GET:    /****/
  224.         if (n > 0) {
  225.             if (isdigit(*xtoken)) {
  226.                 fprintf(stderr,"illegal variable name %s\n",
  227.                 xtoken);
  228.                 break;
  229.             }
  230.             *variable = '\0';
  231.             n = getarg(buf, &i, tbuf3); /* using temp buf3 */
  232.             if (n > 0) {
  233.                 fprintf(stderr,"%s", tbuf3);
  234.                 gets(variable);
  235.  
  236.             }
  237.             if (*variable != '\0')
  238.                 install(xtoken,variable, gentab);
  239.         }
  240.         else
  241.             fprintf(stderr,"%c%s needs a variable name.\n",
  242.             cchar, token);
  243.         break;
  244.     case CL:    /****/
  245.         if (argtyp == '\n') {
  246.             clast->level = 0;
  247.             clast->str = NULL;
  248.         }
  249.         else {
  250.             skipbl(buf,&i);
  251.             if (*(buf+i) == '\0')
  252.                 break;        /* no contents line here ! */
  253.             clast->level = val * 3; /* level * indent        */
  254.             n = i;
  255.             while(*(buf+n) != '\n')
  256.                 n++;
  257.             *(buf+n) = '\0';    /* destroy CR with a null  */
  258.             clast->str = strsave(buf+i);
  259.             clast->page = curpag;
  260.         }
  261.         clast->nextc = (struct clist *) malloc(sizeof(struct clist));
  262.         p_memoryus += sizeof(struct clist);
  263.         clast = clast->nextc;
  264.         clast->nextc = NULL;
  265.         break;
  266.     case PC:    /****/
  267.         lbrk();
  268.         clast = chead;
  269.         while(clast->nextc != NULL) {
  270.             if (clast->str == NULL)
  271.                 put("\n");
  272.             else {
  273.                 tival = (int) clast->level + inval;
  274.                 i = rmval - tival;
  275.                 docline(variable, i, clast->str, clast->page);
  276.                 put(variable);
  277.             }
  278.             clast = clast->nextc;
  279.         }
  280.         break;
  281.     case DBO:    /****/
  282.         bolding = NO;
  283.         break;
  284.     case EBO:    /****/
  285.         bolding = YES;
  286.         break;
  287.     case AP:    /****/
  288.         autopar = YES;
  289.         break;
  290.     case NAP:    /****/
  291.         autopar = NO;
  292.         break;
  293.     case SAV:    /****/
  294.         lbrk();
  295.         save();
  296.         break;
  297.     case RST:    /****/
  298.         lbrk();
  299.         restore();
  300.         break;
  301.     case NPA:    /****/
  302.         paging = NO;
  303.         savpl = plval;
  304.         plval = HUGE;
  305.         bottom = plval - m3val - m4val;
  306.         break;
  307.     case PGI:    /****/
  308.         bottom = lineno - 1;    /* force end-of-page */
  309.         lbrk();
  310.         plval = savpl;
  311.         break;
  312.     case LTR:    /****/
  313.         lbrk();
  314.         if (save()) {
  315.             inval = 0;
  316.             rmval = 132;
  317.             autopar = NO;
  318.             lsval = 0;
  319.             fill = NO;
  320.             literal = YES;
  321.         }
  322.         break;
  323.     case ELT:    /****/
  324.         restore();
  325.         literal = NO;
  326.         break;
  327.     case WR:    /****/
  328.         lbrk();
  329.         getpstr(buf+rest,special);
  330.         defn = special;
  331.         while(*defn)
  332.             putchar(*defn++);
  333.         break;
  334.     case PL:
  335.         if (paging == NO)
  336.             break;
  337.         set(&plval, val, argtyp, PAGELEN,
  338.         m1val + m2val + m3val + m4val + 1, HUGE);
  339.         bottom = plval - m3val - m4val;
  340.         break;
  341.     case PO:
  342.         set(&offset, val, argtyp, 0, 0, rmval - 1);
  343.         break;
  344.     case M1:
  345.         set(&m1val, val, argtyp, 3, 0,
  346.         plval - m2val - m3val - m4val - 1);
  347.         break;
  348.     case M2:
  349.         set(&m2val, val, argtyp, 2, 0,
  350.         plval - m1val - m3val - m4val - 1);
  351.         break;
  352.     case M3:
  353.         set(&m3val, val, argtyp, 2, 0,
  354.         plval - m1val - m2val - m4val - 1);
  355.         bottom = plval - m3val - m4val;
  356.         break;
  357.     case M4:
  358.         set(&m4val, val, argtyp, 3, 0,
  359.         plval - m1val - m2val - m3val - 1);
  360.         bottom = plval - m3val - m4val;
  361.         break;
  362.     case EH:
  363.         gettl(buf, ehead, ehlim);
  364.         break;
  365.     case OH:
  366.         gettl(buf, ohead, ohlim);
  367.         break;
  368.     case EF:
  369.         gettl(buf, efoot, eflim);
  370.         break;
  371.     case OF:
  372.         gettl(buf, ofoot, oflim);
  373.         break;
  374.     case CC:
  375.         cchar = *xtoken;
  376.         if (cchar == '\0' || cchar == '\n')
  377.             cchar = '.';
  378.         if ((lineno + val) > bottom && lineno <= bottom) {
  379.             space(val);
  380.             lineno = 0;
  381.         }
  382.         break;
  383.     case EC:
  384.         genesc = *xtoken;
  385.         if (genesc == '\0' || genesc == '\n')
  386.             genesc = '_';
  387.         break;
  388.     case NE:
  389.         if ((lineno + val) > bottom && lineno <= bottom) {
  390.             space(val);
  391.             lineno = 0;
  392.         }
  393.         break;
  394.     case BS:
  395.         set(&bsval, val, argtyp, 1, 0, HUGE);
  396.         break;
  397.     case JU:
  398.         rjust = YES;
  399.         break;
  400.     case NJ:
  401.         rjust = NO;
  402.         break;
  403.     case SO:
  404.         if (n <= 0)
  405.             return;
  406.         if (level + 1 == NFILES)
  407.             error("? SO commands nested too deeply.");
  408.         if ((infile[level + 1] = fopen(xtoken, "r")) != NULL) {
  409.             level++;
  410.             if (verbose == YES)
  411. #ifdef rainbow
  412.                 fprintf(stderr,"source \033[7m%s\033[0m\n",
  413.                     xtoken);
  414. #else
  415.                 fprintf(stderr,"source %s\n",xtoken);
  416. #endif
  417.         }
  418.         else
  419.             fprintf(stderr,"%s: cannot open.\n",xtoken);
  420.         break;
  421.     case OU:    /*****/
  422.         /* skip for now. */
  423.         break;
  424.  
  425.     case OE:    /*****/
  426.         /* skip for now. */
  427.         break;
  428.  
  429.     case CU:
  430.         ulblnk = '_';
  431.         set(&ulval, val, argtyp, 0, 1, HUGE);
  432.         break;
  433.     case DE:
  434.         dodef(buf, infile[level]);
  435.         break;
  436.     case NR:
  437.         if (n <= 0)
  438.             return;
  439.         if (*xtoken < 'a' || *xtoken > 'z')
  440.             error("invalid number register [%c].",*xtoken);
  441.  
  442.         val = getval(buf, &i, &argtyp);
  443.         set(&nr[xtoken[0] - 'a'], val, argtyp, 0, -HUGE, HUGE);
  444.         break;
  445.     case ST:
  446.         if (argtyp == '-')
  447.             spval = plval;
  448.         else
  449.             spval = 0;
  450.         set(&spval, val, argtyp, 0, 1, bottom);
  451.         if (spval > lineno && lineno == 0)
  452.             phead();
  453.         if (spval > lineno)
  454.             space(spval - lineno);
  455.         break;
  456.     case RESET:    /****/
  457.         finit();
  458.         break;
  459.     default:
  460.         error("? Botch in command.");
  461.         break;
  462.     }
  463. }
  464.  
  465. /*
  466.  * comtype - decode the command type
  467.  *
  468.  */
  469. int
  470. comtype(buf, siz, defn, flags)
  471. char buf[];
  472. int siz;
  473. char **defn;
  474. int *flags;
  475. {
  476.     struct hashlist *np;
  477.     struct lexlist *xp;
  478.     extern    struct lexlist *lexlook();
  479.     int i,comtyp;
  480.     char c1,c2;
  481.  
  482. #ifdef DEBUG
  483.     printf("comtype: %s (token)\n", buf);
  484. #endif
  485.  
  486.     if ((np = lookup(buf, macrotab)) != NULL) {
  487.         *defn=np->def;
  488.         return(MACRO);
  489.     }
  490.     comtyp = UNKNOWN;
  491.  
  492.     if (*buf == '#' || *buf == '!')
  493.         return(comtyp);
  494.  
  495.     if ((xp = lexlook(buf,lextab)) != NULL)
  496.         if (onlyrunoff && (xp->flag != RUNOFF)) {
  497.             fprintf(stderr,"%c%s is not a runoff command.\n",
  498.             cchar,buf);
  499.             return(UNKNOWN);
  500.         }
  501.         else {
  502.             comtyp = xp->val;
  503.             *flags = xp->flag;
  504.         }
  505.  
  506.     if (comtyp == UNKNOWN)
  507.         fprintf(stderr,"unknown command %c%s\n",cchar,buf);
  508.     return(comtyp);
  509. }
  510.